/**
 * @(#)TaskViewActivity.java        1.0 2/28/12
 * 
 * Copyright (c) 2012 public static droid main
 * Georgia Institute of Technology, Atlanta, GA
 * All rights reserved.
 */

package edu.gatech.oad.publicstaticdroidmain.taskmanager.ui;

import java.text.DateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;
import edu.gatech.oad.publicstaticdroidmain.taskmanager.model.Task;
import edu.gatech.oad.publicstaticdroidmain.taskmanager.model.TaskManager;

/**
 * An Android activity that allows a user to view a list of all of 
 * their Tasks.
 * 
 * @version 1.0 Feb 22 2012
 * @author Raheel Merali
 */
public class TaskViewActivity extends AbstractTaskManagerActivity {

    private static final int DATE_DIALOG_ID = 0;
    
    //Filtering options from which the user can pick
    private static final String[] FILTER_OPTIONS = {"View All", "Filter by Category", "Filter by Date", "Filter by Completed", "Filter by Not Completed"};
   
    //Variables that represent the different filtering options
    private static final int FILTER_ALL = 0;
    private static final int FILTER_CATEGORY = 1;
    private static final int FILTER_DATE = 2;
    private static final int FILTER_COMPLETED = 3;
    private static final int FILTER_NOT_COMPLETED = 4;
    
    /* The key used for the task ID when the ID is being passed to TaskEditActivity */
    public static final String TASK_ID_KEY = "TASKID";
    
    private int currentFilter;
    private String categoryBeingFilteredBy;
    private Date dateBeingFilteredBy;
    private TextView filterLabel;

    private OnClickListener buttonListener;
    private TaskManager taskManager;

    private ImageButton map;
    private ImageButton delete;
    private ImageButton add;
    private Button complete;

    private ListView list;
    private TaskArrayAdapter taskListAdapter;
    private Spinner filterSpinner;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.task_view);

	list = (ListView) findViewById(R.id.list);
	filterSpinner = (Spinner) findViewById(R.id.category_filter);
	map = (ImageButton) findViewById(R.id.map);
	delete = (ImageButton) findViewById(R.id.delete);
	add = (ImageButton) findViewById(R.id.add);
	complete = (Button) findViewById(R.id.complete);
	filterLabel = (TextView) findViewById(R.id.taskViewFilterLabel);

	buttonListener = new TaskViewButtonListener();
	
	add.setOnClickListener(buttonListener);
	delete.setOnClickListener(buttonListener);
	map.setOnClickListener(buttonListener);
	complete.setOnClickListener(buttonListener);

	taskManager = ((TaskManagerApplication)getApplication()).getTaskManager();

	taskListAdapter = new TaskArrayAdapter(this);
	list.setAdapter(taskListAdapter);
	list.setOnItemClickListener(new TaskSelectedListener());
	
	setUpFilterSpinner();
    }
    
    @Override
    public void onResume() {
	super.onResume();
	refreshCurrentlyDisplayedTasks();
    }

    /**
     * Sends the tapped Task's ID to NewTaskActivity
     */
    private class TaskSelectedListener implements OnItemClickListener {
	public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
	    Task selectedTask = (Task) parent.getAdapter().getItem(position);
	    Intent taskEditIntent = new Intent();
	    Bundle taskBundle = new Bundle();
	    taskBundle.putLong(TASK_ID_KEY, selectedTask.getId());
	    taskEditIntent.putExtras(taskBundle);
	    startUIActivityWithIntent(getString(R.string.activity_new_task), taskEditIntent);
	}
	
    }
    
    /**
     * creates a drop down with categories as choices
     */
    private void setUpFilterSpinner() {
	ArrayAdapter<String> filterAdapter = new ArrayAdapter<String>(this, 
		android.R.layout.simple_spinner_item, 
		FILTER_OPTIONS);
	filterAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
	filterSpinner.setAdapter(filterAdapter);
	filterSpinner.setOnItemSelectedListener(new FilterSpinnerListener());
    }

    /**
     * Displays all of a user's Tasks in the ListView.
     */
    private void displayAllTasks() {
	taskListAdapter.displayTaskArray(taskManager.getAllTasks());
	filterLabel.setVisibility(View.GONE);
	currentFilter = FILTER_ALL;
    }

    /**
     * Filters the ListView so it only shows Tasks in the specified category.
     * 
     * @param category the category to filter by
     */
    private void filterTaskListByCategory(String category) {
	taskListAdapter.displayTaskArray(taskManager.getTasksInCategory(category));
	categoryBeingFilteredBy = category;
	filterLabel.setVisibility(View.VISIBLE);
	filterLabel.setText("Viewing Tasks in Category \"" + category + "\"");
	currentFilter = FILTER_CATEGORY;
    }

    /**
     * Filters the ListView so it only shows Tasks on or after the specified
     * due date.
     * 
     * @param category the due date
     */
    private void filterTaskListByDate(Date start) {
	taskListAdapter.displayTaskArray(taskManager.getTasksAfterDate(start));
	dateBeingFilteredBy = start;
	filterLabel.setVisibility(View.VISIBLE);
	DateFormat formatter = DateFormat.getDateInstance(DateFormat.MEDIUM);
	String dateString = formatter.format(start);
	filterLabel.setText("Viewing Tasks After " + dateString);
	currentFilter = FILTER_DATE;
    }
    
    /**
     * Filters the ListView so it only shows Tasks with the specified
     * completion status.
     * 
     * @param category the completion status to filter by
     */
    private void filterTaskListByCompletionStatus(boolean completionStatus) {
	if (completionStatus) {
	    currentFilter = FILTER_COMPLETED;
	    filterLabel.setText("Viewing Completed Tasks");
	} else {
	    currentFilter = FILTER_NOT_COMPLETED;
	    filterLabel.setText("Viewing Not Completed Tasks");
	}
	
	taskListAdapter.displayTaskArray(taskManager.getTasksWithCompletionStatus(completionStatus));
	
	filterLabel.setVisibility(View.VISIBLE);
	
    }
    
    /**
     * Refreshes the ListView so that it shows the most recent data.  Keeps the filter
     * currently being used the same, so if only Tasks in a certain category are being
     * displayed, only Tasks in that category will continue to be displayed.
     */
    private void refreshCurrentlyDisplayedTasks() {
	switch(currentFilter) {
	case FILTER_ALL:
	    displayAllTasks();
	    break;
	case FILTER_CATEGORY:
	    filterTaskListByCategory(categoryBeingFilteredBy);
	    break;
	case FILTER_DATE:
	    filterTaskListByDate(dateBeingFilteredBy);
	    break;
	case FILTER_COMPLETED:
	    filterTaskListByCompletionStatus(true);
	    break;
	case FILTER_NOT_COMPLETED:
	    filterTaskListByCompletionStatus(false);
	    break;
	}
    }

    /**
     * A listener for the date picker dialog that filters the
     * ListView by due date once a date is selected by the user.
     */
    private DatePickerDialog.OnDateSetListener mDateSetListener =  
	    new DatePickerDialog.OnDateSetListener() {  
	public void onDateSet(DatePicker view, int year,  
		int monthOfYear, int dayOfMonth) { 
	    Date date = new Date();
	    date.setYear(year - 1900);
	    date.setMonth(monthOfYear);
	    date.setDate(dayOfMonth);
	    date.setHours(0);
	    date.setMinutes(0);
	    date.setSeconds(0);

	    filterTaskListByDate(date);
	}
    }; 

    /**
     * Creates a new DatePicker dialog that will allow the user
     * to pick a date to filter Tasks by.
     * 
     * @param id the id of the type of dialog to create
     */
    @Override
    protected Dialog onCreateDialog(int id) {  
	switch (id) {  
	case DATE_DIALOG_ID:  
	    Calendar calendar = Calendar.getInstance();
	    int year = calendar.get(Calendar.YEAR);
	    int month = calendar.get(Calendar.MONTH);
	    int day = calendar.get(Calendar.DAY_OF_MONTH);

	    return new DatePickerDialog(this, mDateSetListener, year, month, day);  
	}  
	return null;  

    }

    /**
     * A listener that handles filtering via the associated spinner.
     */
    private class FilterSpinnerListener implements OnItemSelectedListener {

	public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
	    switch(pos)
	    {
	    case FILTER_ALL:
		displayAllTasks();
		break;
	    case FILTER_CATEGORY:
		AlertDialog.Builder categoryDialogBox = new AlertDialog.Builder(TaskViewActivity.this);
		categoryDialogBox.setTitle("Select a Category");
		categoryDialogBox.setItems(taskManager.getCategories(), new DialogInterface.OnClickListener() {
		    public void onClick(DialogInterface dialog, int which) {
			String[] categories = taskManager.getCategories();
			String selectedCategory = categories[which];
			filterTaskListByCategory(selectedCategory);
		    }
		});

		categoryDialogBox.show();

		break;
	    case FILTER_DATE:
		showDialog(DATE_DIALOG_ID);
		break;
	    case FILTER_COMPLETED:
		filterTaskListByCompletionStatus(true);
		break;
	    case FILTER_NOT_COMPLETED:
		filterTaskListByCompletionStatus(false);
		break;
	    }

	}

	public void onNothingSelected(AdapterView<?> arg0) {
	    
	}

    }

    /**
     * A listener that handles button presses.
     */
    private class TaskViewButtonListener implements OnClickListener {

	/**
	 * handles button clicks
	 */
	public void onClick(View view) {
	    switch(view.getId()) {
	    case R.id.add:
		try {
		    String fullyQualifiedName = getString(R.string.ui_package_name) + getString(R.string.activity_new_task);
		    Class<?> classToLaunch = Class.forName(fullyQualifiedName);
		    Intent classLaunchIntent = new Intent(TaskViewActivity.this, classToLaunch);
		    Bundle b = new Bundle();
		    //b.putSerializable("task", (Serializable) new Task("test1", "test1", new Date(), 4534.3, 34543.4, Task.Recurrence.ONCE));
		    classLaunchIntent.putExtras(b);
		    startActivity(classLaunchIntent);
		}
		catch(ClassNotFoundException e) {
		    e.printStackTrace();
		}
		break;
	    case R.id.delete:

		List<Task> checkedTasksDelete = taskListAdapter.getCheckedTasks();

		for (Task t : checkedTasksDelete) {
		    taskManager.removeTask(t);
		}

		refreshCurrentlyDisplayedTasks();
		
		break;
	    case R.id.map:
		startUIActivity(getString(R.string.activity_map_view));
		break;
	    case R.id.complete:
		List<Task> checkedTasks = taskListAdapter.getCheckedTasks();

		for (Task t : checkedTasks) {
		    t.setCompleted(!t.isCompleted());
		    taskManager.updateTask(t);
		}

		refreshCurrentlyDisplayedTasks();

		break;
	    }
	}

    }

}